package com.journaldev.threadpool.poolexecutor2;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

import com.journaldev.threadpool.poolexecutor.RejectedExecutionHandlerImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 等待线程池中的消息都处理完毕代码段，其实只是起到一个计算用时的作用，没别的意义。
 * 如果碰到Worker任务执行时间比较长的情况，那么这个timeout的用法就值得商榷了。
 * 测试结果是：
 * <main> - 线程池所有任务已经完成。timeout=-1
 * 可见不准确，会产生负数。
 * 虽然如此，它可以给我们提供一个可预见性参与，线程池shutdown()方法，还是会员等待队列中所有的任务完成才关闭的。
 */
public class InviteTask {

	private static final Logger logger = LoggerFactory.getLogger(InviteTask.class);

	int limitCount = 10 ;
//	int current;
	private static AtomicInteger current = new AtomicInteger(0);

	public static void main(String[] args)  throws InterruptedException {
		RejectedExecutionHandlerImpl rejectedHandler = new RejectedExecutionHandlerImpl();
		ThreadFactory threadFactory = Executors.defaultThreadFactory();
		ThreadPoolExecutor executorPool = new ThreadPoolExecutor(2, 4, 10, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(2), threadFactory, rejectedHandler);
		for(int i=0; i < 2; i++){
			executorPool.execute(new InviteTask().new InviteMemberTask("cmd"+i));
		}
		executorPool.shutdown();


		// 等待线程池中的消息都处理完毕，然后关闭
		try {
			// 最大等待时间（秒），防止一直无限循环下去。
			int timeout = 300;
			// 每次检查超时时间
			int waittime = 2;
			boolean loop = true;
			do {
				// 循环检查线程池中所有任务是否都完成，
				loop = !executorPool.awaitTermination(waittime, TimeUnit.SECONDS);
				timeout = timeout - waittime;
			} while (loop && timeout > 0);
			logger.info("线程池所有任务已经完成。timeout=" + timeout);
		} catch (InterruptedException e) {
			logger.error("等待邀约任务执行完过程中出现异常。", e);
		}
	}

	class InviteMemberTask implements Runnable {

		private String command;

		public InviteMemberTask(String command) {
			this.command = command ;
		}

		@Override
		public void run() {
			System.out.println(Thread.currentThread().getName()+" Start. Command = "+ command);
			while (true) {
				System.out.println(Thread.currentThread().getName()+ " Hello number : "+ current.incrementAndGet());
				/*********************假装在执行一个任务*********************/
				try {
					Thread.sleep(50);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				/*********************假装在执行一个任务*********************/
				if (current.get() == limitCount){
					break ;
				}
			}
			System.out.println(Thread.currentThread().getName()+" End. ");
		}
		
	}
}
